package cn.agiledata.bank.webService;

import cn.agiledata.bank.common.dao.AccountTemplate;
import cn.agiledata.bank.common.dao.ActionTypeTemplate;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.WeatherUtil;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.hibernateBean.SubAccount;
import cn.agiledata.bank.hibernateBean.Transaction;
import cn.agiledata.bank.transaction.service.GetTransaction;
import cn.agiledata.bank.transaction.service.GetTransactionImpl;
import cn.agiledata.bank.transaction.service.TransactionFactory;

import com.vnv.infrastructure.exception.IPBException;
import com.vnv.infrastructure.logic.IPBAppFactory;
import com.vnv.infrastructure.logic.IPBMgrFactory;

import org.example.transaction.TransactionType;
import org.example.transaction.TransactionsDocument;

import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.Date;


public class J2MEInterface {
    public String tranBalance(final String xmlObject) throws Exception {
        final AccountTemplate at = (AccountTemplate) IPBMgrFactory.getMgr(
                "accountTemplate");
        this.addTranCollBack(new TransactionCallback() {
                public Object doInTransaction(TransactionStatus status) {
                    TransactionsDocument td = null;

                    try {
                        td = TransactionsDocument.Factory.parse(xmlObject);
                    } catch (Exception e) {
                        // TODO: handle exception
                    }

                    TransactionType[] transaction = td.getTransactions()
                                                      .getTransactionArray();

                    for (int i = 0; i < transaction.length; i++) {
                        TransactionType trantype = transaction[i];
                        SubAccount DebitSubAccount = getJ2MEAccountByNameOrPhone(at,
                                trantype.getDebitAccount());

                        if (DebitSubAccount == null) {
                            //付款方不存在
                            return "1";
                        }

                        if (DebitSubAccount.getAccountBalance().getBalance()
                                               .doubleValue() <= 0) {
                            //付款方没有足够资金
                            return "-5";
                        }

                        SubAccount CreditSubAccount = getJ2MEAccountByNameOrPhone(at,
                                trantype.getCreditAccount());

                        if (CreditSubAccount == null) {
                            //收款方不存在手机子账户
                            return "2";
                        }

                        Transaction tran = pickUpTran(trantype.getTransId(),
                                new Double(trantype.getFeeValue()),
                                DebitSubAccount, CreditSubAccount,
                                Constant.ACTION_TYPE_C);
                        saveTransaction(tran, Constant.ACTION_TYPE_C);
                    }

                    return null;
                }
            });

        return "OK";
    }

    private Object addTranCollBack(TransactionCallback call)
        throws Exception {
        PlatformTransactionManager tm = (DataSourceTransactionManager) IPBAppFactory.getObj(
                "transactionManager-sql");
        TransactionTemplate tt = new TransactionTemplate(tm);

        return tt.execute(call);
    }

    private SubAccount getJ2MEAccountByNameOrPhone(AccountTemplate at,
        String name) {
        Account MainAccount = at.getAccountByName(name);

        return at.getJ2MESubAccount(MainAccount.getId().toString());
    }

    /**
     * 此方法为j2me手机后台提供web service 充值接口
     *
     * AccountEmailOrMobile 账户email或者手机号码
     * password             账户密码
     * pickUpPass           支付密码
     * tranId               交易流水号
     * money                充值金额
     * @return 充值后的金额
     * @throws
     *  -1 此主账户不存在
            -2 此主账户未开通手机子账户
            -3 登录密码不正确
            -4 支付密码不正确
            -5 主账户余额不足
            -6 充值失败，可能是系统网络故障，稍后再试
     */
    public Double addMoney(String AccountEmailOrMobile, String password,
        String pickUpPass, String tranId, Double money)
        throws Exception {
        AccountTemplate at = (AccountTemplate) IPBMgrFactory.getMgr(
                "accountTemplate");

        Account loginAccount = at.getAccountByName(AccountEmailOrMobile);

        if (loginAccount == null) {
            return new Double(-1);
        }

        SubAccount j2meSubAccount = at.getJ2MESubAccount(loginAccount.getId()
                                                                     .toString());

        if (j2meSubAccount == null) {
            return new Double(-2);
        }

        Double j2meSubAccountBalanace = j2meSubAccount.getAccountBalance()
                                                      .getBalance();

        if ((loginAccount != null) &&
                loginAccount.getLoginPassword().equals(password)) {
            if (loginAccount.getPayPassword().equals(pickUpPass)) {
                String actionType = Constant.ACTION_TYPE_H;
                Transaction tran = pickUpTran(tranId, money,
                        loginAccount.getDefaultSubAccount(), j2meSubAccount,
                        actionType);

                if (tran.getDebit().getAccountBalance().getBalance()
                            .doubleValue() < money.doubleValue()) {
                    return new Double(-5);
                }

                saveTransaction(tran, actionType);

                j2meSubAccountBalanace = j2meSubAccount.getAccountBalance()
                                                       .getBalance();
            } else {
                return new Double(-4);
            }
        } else {
            return new Double(-3);
        }

        return j2meSubAccountBalanace;
    }

    /**
     * 结算过程
     * @param result
     * @return
     */
    public String balanceTransaction(String xmlObject)
        throws Exception {
        AccountTemplate at = (AccountTemplate) IPBMgrFactory.getMgr(
                "accountTemplate");

        /*                Account MainAccount =
                                at.getAccountByName(mainAccountId);
                        Account CreditAccount =
                                at.getAccountByName(creditAccountId);*/
        TransactionsDocument td = TransactionsDocument.Factory.parse(xmlObject);
        TransactionType[] transaction = td.getTransactions()
                                          .getTransactionArray();

        for (int i = 0; i < transaction.length; i++) {
            TransactionType tran = transaction[i];
        }

        return "0";
    }

    private Double saveTransaction(Transaction tran, String actionType) {
        GetTransaction getTran = new GetTransactionImpl();
        TransactionFactory tt = getTran.getTransaction(actionType);

        try {
            tt.saveTransaction(tran);

            return new Double(0);
        } catch (RuntimeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

            return new Double(-6);
        }
    }

    private Transaction pickUpTran(String tranId, Double money,
        SubAccount loginAccount, SubAccount j2meSubAccount, String actionType) {
        Transaction tran = new Transaction();
        tran.setTransId(tranId);

        try {
            ActionTypeTemplate att = (ActionTypeTemplate) IPBMgrFactory.getMgr(
                    "actionTypeTemplate");
            tran.setActionType(att.getActionTypeById(Long.parseLong(
                        Constant.ACTION_TYPE_H)));
        } catch (Exception e) {
            // TODO: handle exception
        }

        tran.setDebit(loginAccount);

        tran.setCredit(j2meSubAccount);

        tran.setAmount(money);
        tran.setTransStatus(Constant.TRANS_STATUS_TRANSACTIONSUCCESS);

        tran.setBeginDate(new Date());
        WeatherUtil.fillCreateAndUpdateInfo(tran,
            loginAccount.getId().toString());

        return tran;
    }
}
